package com.nowcoder.community.controller;

import com.nowcoder.community.util.CommunityUtil;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

@Controller
@RequestMapping(path = "/alpha")
public class AlphaController {

    @RequestMapping(path = "/hello")
    @ResponseBody
    public String sayHello() {
        return "Hello SpringBoot";
    }

    @RequestMapping(path = "/http")
    public void http(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {
        // 获取请求数据
        System.out.println(httpRequest.getMethod());
        System.out.println(httpRequest.getServletPath());
        Enumeration<String> enumeration = httpRequest.getHeaderNames();
        while(enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            String value = httpRequest.getHeader(key);
            System.out.println(key + ": " + value);
        }

        System.out.println(httpRequest.getParameter("code"));

        // 向浏览器返回响应数据
        httpResponse.setContentType("text/html;charset=utf-8");
        try (PrintWriter writer = httpResponse.getWriter()) {
            writer.write("<h1>你好呀!</h1>");
        } catch(IOException e) {
            e.printStackTrace();
        }
    }

    // 处理GET请求
    // url: /students?current=1&limit=20
    @RequestMapping(path = "/students", method = RequestMethod.GET)
    @ResponseBody
    public String getStudents(
            @RequestParam(name = "current", required = false, defaultValue = "1") int current,
            @RequestParam(name = "limit", required = false, defaultValue = "10") int limit)
    {
        System.out.println("current: " + current);
        System.out.println("limit: " + limit);
        return "Some Students";
    }

    // 将服务端需要获取的参数放在请求url中
    // url: /students/123
    @RequestMapping(path = "/student/{stuId}", method = RequestMethod.GET)
    @ResponseBody
    public String getStudent(@PathVariable("stuId") String id) {
        System.out.println("Student's id is: " + id);
        return "A Student";
    }

    // 客户端向服务器提交数据
    // POST请求
    /**
     * 为什么向后端传数据使用POST请求
     * 使用GET会导致：1.所传数据的名称和值出现在用户可见的url中；2.浏览器所允许的url长度是有限制的
     */
    @RequestMapping(path = "/student", method = RequestMethod.POST)
    @ResponseBody
    public String saveStudent(String name, String age) {
        System.out.println("学生的姓名是: " + name);
        System.out.println("学生的年龄是: " + age);
        return "Success";
    }

    // 响应HTML数据 -> 也就是返回一个动态的网页
    // 如果向返回html数据, 则不加@ResponseBody注解
    @RequestMapping(path = "/teacher", method = RequestMethod.GET)
    public ModelAndView getTeacher() {
        ModelAndView mav = new ModelAndView();
        mav.addObject("name", "Jack");
        mav.addObject("age", 30);
        // 视图文件在/templates目录下
        mav.setViewName("/demo/view");
        return mav;
    }

    @RequestMapping(path = "/school", method = RequestMethod.GET)
    public String getSchool(Model model) {
        model.addAttribute("schoolName", "The Chinese University of Hong Kong");
        model.addAttribute("schoolAge", 100);
        return "/demo/view";
    }

    // 向浏览器响应JSON数据 -> 加一个ResponseBody注解
    // 比如返回一个JAVA对象，则可以利用JSON，将JAVA对象转化成一种可以和JS中对象相互适配的格式，也就是一个string
    /**
     * 通常在异步请求中，需要服务器向前端返回JSON数据
     * 异步请求简单来说就是：当前页面不刷新，却也向服务端发送请求并得到了响应数据
     */
    @RequestMapping(path = "/emp", method = RequestMethod.GET)
    @ResponseBody
    public Map<String, Object> getEmp() {
        Map<String, Object> map = new HashMap<>();
        map.put("name", "Sam");
        map.put("age", 27);
        map.put("salary", 8000.00);
        return map;
    }

    @RequestMapping(path = "/emps", method = RequestMethod.GET)
    @ResponseBody
    public List<Map<String, Object>> getEmps() {

        List<Map<String, Object>> rtn = new ArrayList<>();

        Map<String, Object> student1 = new HashMap<>();
        student1.put("name", "Sam");
        student1.put("age", 27);
        student1.put("salary", 8000.00);
        rtn.add(student1);

        Map<String, Object> student2 = new HashMap<>();
        student2.put("name", "Peter");
        student2.put("age", 30);
        student2.put("salary", 10000.00);
        rtn.add(student2);

        return rtn;
    }

    // 测试服务端创建Cookie
    @RequestMapping(path = "/cookie/set", method = RequestMethod.GET)
    @ResponseBody
    public String setCookie(HttpServletResponse response) {
        // 每个Cookie对象只能存储一对KV
        Cookie cookie = new Cookie("code", CommunityUtil.generateUUID());
        // cookie对象只在/community/alpha路径和其子路径下有效
        cookie.setPath("/community/alpha");
        // 设置cookie的有效时间
        // 默认cookie对象存储在浏览行运行时被分配的内存中，浏览器关闭则删除
        cookie.setMaxAge(60 * 10);
        // 将cookie对象放在服务器response的头
        response.addCookie(cookie);
        return "set cookie";
    }

    @RequestMapping(path = "/cookie/get", method = RequestMethod.GET)
    @ResponseBody
    public String setMoreCookies(@CookieValue("code") String code) {
        System.out.println("Cookie's code: " + code);
        return "cookie";
    }

    // 测试服务端创建并保存session

    /**
     * session对象可以由SpringMVC自动创建并注入
     *
     * @param
     * @return
     */
    @RequestMapping(path = "/session/set", method = RequestMethod.GET)
    @ResponseBody
    public String setSession(HttpSession session) {
        session.setAttribute("id", 1);
        session.setAttribute("name", "Mario");
        return "Set Session";
    }

    // 测试浏览器向服务端回传session id
    @RequestMapping(path = "/session/get", method = RequestMethod.GET)
    @ResponseBody
    public String getSession(HttpSession session) {
        System.out.println("session's id: " + session.getId());
        System.out.println(session.getAttribute("id"));
        System.out.println(session.getAttribute("name"));
        return "Get Session";
    }

    // AJAX实例
    @RequestMapping(path = "/ajax", method = RequestMethod.POST)
    @ResponseBody
    public String testAjax(String name, int age) {
        System.out.println(name + age);
        return CommunityUtil.getJsonString(0, "操作成功");
    }

}
